/**
 * 
 */
package edu.arizona.bio5.onto.decomposition.persistent;

import java.net.URI;
import java.util.Map;
import java.util.Set;

import org.semanticweb.owlapi.model.OWLAxiom;

import uk.ac.manchester.cs.graph.DirectedGraph;
import uk.ac.manchester.cs.graph.DirectedGraphImpl;
import uk.ac.manchester.cs.owlapi.modularity.ModuleType;
import edu.arizona.bio5.onto.decomposition.Atom;
import edu.arizona.bio5.onto.decomposition.AtomicDecomposition;
import edu.arizona.bio5.onto.decomposition.MemAtom;

/**
 * Atomic decomposition backed by a set of files which store the atoms, dependencies, labels and indexes
 * 
 * @author Pavel Klinov
 *
 */
public class PersistentAtomicDecompositionImpl extends AtomicDecomposition implements PersistentAtomicDecomposition {

	public PersistentAtomicDecompositionImpl(	URI ontoURI,
												DirectedGraph<Atom, Object> adGraph,
												Map<URI, Set<Atom>> termIndex,
												ModuleType type) {
		super(ontoURI, type);
		//Init
		m_adGraph = adGraph;
		m_adInvGraph = invertGraph(adGraph);
		m_termBasedIndex = termIndex;
	}

	protected void setADGraph(DirectedGraph<Atom, Object> adGraph) {
		m_adGraph = adGraph;
		m_adInvGraph = invertGraph(adGraph);
	}
	
	/*
	 *  Loads every single atom from disk
	 */
	public void loadEverything() throws ADPersistenceException {
		
		System.out.print("Loading axioms...");
		
		for (Atom atom : getAtoms()) {
			
			PersistentAtom pAtom = (PersistentAtom) atom;
			
			if (!pAtom.isLoaded()) pAtom.loadAxioms();
		}
		
		System.out.println("done!");
	}

	/*
	 * Primarily for evaluation
	 */
	public void unloadEverything() throws ADPersistenceException {
		
		for (Atom atom : getAtoms()) {
			
			((PersistentAtom)atom).unloadAxioms();
		}
	}	
	
	/*
	 * TODO Probably should be a generic graph method
	 */
	private DirectedGraph<Atom, Object> invertGraph(DirectedGraph<Atom, Object> adGraph) {

		if (adGraph == null) {
			return null;
		}
		
		DirectedGraph<Atom, Object> invGraph = new DirectedGraphImpl<Atom, Object>();
		
		for (Atom atom : adGraph.getVertices()) {
			
			invGraph.addVertex(atom);
			
			for (Atom adjacent : adGraph.getAdjacentVertices(atom)) {
				
				invGraph.addEdge("", adjacent, atom);
			}
		}
		
		return invGraph;
	}	

	@Override
	public Atom getAtomForAxiom(OWLAxiom axiom) {
		
		throw new UnsupportedOperationException();
	}


	@Override
	public MemAtom addAtom(Set<OWLAxiom> axioms) {
		
		throw new UnsupportedOperationException();
	}

	@Override
	public void addAxiomToAtom(OWLAxiom axiom, MemAtom atom) {
		
		throw new UnsupportedOperationException();
	}

	@Override
	public void addDependency(Atom dependentAtom, Atom dependentUponAtom) {
		
		throw new UnsupportedOperationException();
	}

	@Override
	protected void removeDependency(Atom dependentAtom, Atom dependentUponAtom) {
		
		throw new UnsupportedOperationException();
	}

	@Override
	public void close() {
		for (Atom atom : getAtoms()) {		
			PersistentAtom pAtom = (PersistentAtom) atom;
			//close any connections, etc
			pAtom.getLoader().close();
		}
	}
	
}